/*
* Copyright © Shanghai Awinic Technology Co., Ltd. 2020-2020. All rights reserved.
* Description: The header file of the I2C related driver library.
* Date： 20201126
* Awinic_Version： aw_soc_driver_v1.0.0
*/
#include "compile_option.h"
#ifdef AW_86802

#ifndef __AW8680X_I2C_H
#define __AW8680X_I2C_H

/* Include ------------------------------------------------------------------*/
#include "aw8680x_def.h"

/**
  * @brief I2c mode enumeration definition
  */
enum i2c_mode {
	I2C_MODE_NONE = 0x00U,		// No i2c communication on going
	I2C_MODE_MASTER = 0x10U,	// I2C communication is in Master Mode
	I2C_MODE_SLAVE = 0x20U,		// I2C communication is in Slave Mode
	I2C_MODE_MEM = 0x40U,		// I2C communication is in Memory Mode
};
typedef enum i2c_mode I2C_MODE_TYPE_E;

/**
  * @brief I2C speed enumeration definition
  */
enum i2c_speed {
	I2C_STAND_MODE = 0x02U,		// Standard mode (0 to 100Kb/S)
	I2C_FAST_MODE = 0x04U,		// Fast mode (<= 400Kb/S) or fast mode plus (<= 1000Kb/S)
};
typedef enum i2c_speed I2C_SPEED_TYPE_E;

/**
  * @brief I2C status enumeration definition
  */
enum g_i2c_status{
	I2C_NOEVENT = 0x00U,
	I2C_RX_BUSY = 0x01U,
	I2C_RX_END = 0x02U,
	I2C_TX_BUSY = 0x03U,
	I2C_TX_END = 0x04U,
	I2C_STAR = 0x05U,
	I2C_BUSY = 0x06U,
	I2C_RX_REG_BUSY	= 0x07U,
};
typedef enum g_i2c_status I2C_STATUS_TYPE_E;

/** @defgroup I2C_Configuration_Structure_definition I2C Configuration Structure definition
  * @brief  I2C Configuration Structure definition
  */
struct i2c_init_struct {
	AW_U8 i2c_addr;					// I2C address
	AW_U8 fifo_rx_tl;				// I2C Receiving FIFO Threshold Register
	AW_U8 fifo_tx_tl;				// I2C Send FIFO Threshold Register
	AW_U8 sda_setup;				// I2C SDA Establishment Time Register
	AW_U8 spklen;					// Standard and Fast Mode Filter Registers
	AW_U16 scl_hcnt;				// Fast Mode I2C Clock SCL High Level Meter
	AW_U16 scl_lcnt;				// Fast Mode I2C Clock SCL Low Level Meter
	AW_U16 sda_hold;				// SDA Hold Time Control Register
	I2C_SPEED_TYPE_E i2c_speed_e;	// I2C speed mode
};
typedef struct i2c_init_struct I2C_INIT_TYPE_S;

/** @defgroup I2C_handle_Structure_definition I2C handle Structure definition
  * @brief    I2C handle Structure definition
  */
struct i2c_handle {
	IRQ_PRI_E i2c_irq_pri_e;			// I2C irq priority
	I2C_INIT_TYPE_S init_s;				// I2C communication parameters
	I2C_MODE_TYPE_E mode_e;				// I2C communication mode
};
typedef struct i2c_handle I2C_HANDLE_TYPE_S;

/* I2C mode */
#define I2C_CHECK_MODE(mode) (((mode) == I2C_MODE_MASTER) || \
								((mode) == I2C_MODE_SLAVE))
/* I2C address */
#define I2C_CHECK_ADDR(address) ((address) <= 0x3FFU)
/* I2C speed */
#define I2C_CHECK_SPEED(speed) (((speed) == I2C_STAND_MODE) || \
								((speed) == I2C_FAST_MODE))
/* I2C fifo rx tl */
#define I2C_CHECK_RX_TL(fifo_rx_tl) ((fifo_rx_tl) < 0x08U)
/* I2C fifo tx tl */
#define I2C_CHECK_TX_TL(fifo_tx_tl) ((fifo_tx_tl) < 0x08U)
/* I2C sda setup */
#define I2C_CHECK_SDA_SETUP(sda_setup) (((sda_setup) > 0x02U) || ((sda_setup) < 0xFFU))
/* I2C FS spklen */
#define I2C_CHECK_FS_SPKLEN(fs_spklen) ((fs_spklen) < 0xFFU)
/* I2C HS spklen */
#define I2C_CHECK_HS_SPKLEN(hs_spklen) ((hs_spklen) < 0xFFU)
/* I2C SS SCL Hcnt */
#define I2C_CHECK_SS_SCL_HCNT(ss_scl_hcnt) (((ss_scl_hcnt) > 0x06U) || ((ss_scl_hcnt) < 0xFFF5U))
/* I2C SS SCL Lcnt */
#define I2C_CHECK_SS_SCL_LCNT(ss_scl_lcnt) (((ss_scl_lcnt) > 0x08U) || ((ss_scl_lcnt) < 0xFFF5U))
/* I2C HS SCL Hcnt */
#define I2C_CHECK_FS_SCL_HCNT(fs_scl_hcnt) (((fs_scl_hcnt) > 0x06U) || ((fs_scl_hcnt) < 0xFFF5U))
/* I2C HS SCL Lcnt */
#define I2C_CHECK_FS_SCL_LCNT(fs_scl_lcnt) (((fs_scl_lcnt) > 0x08U) || ((fs_scl_lcnt) < 0xFFF5U))
/* I2C SDA hold */
#define I2C_CHECK_SDA_HOLD(sda_hold) ((sda_hold) < 0xFFFFU)

/* Bit definition for I2C register */
#define I2C_CLEAN_DATA			((AW_U32)0x00000000)	// Clean all register data
#define I2C_ENABLE_EN			((AW_U32)0x00000001)	// Enabling I2C
#define I2C_DIS_ENABLE			(~I2C_ENABLE_EN) 		// Disable I2C
#define I2C_SLAVE_EN			((AW_U32)0xFFFFFFBF)	// Enabling I2C slave mode 0xFFFFFFBF
#define I2C_SLAVE_DIS			(~I2C_SLAVE_EN)			// Disanbling I2C slave mode
#define I2C_RESTART_EN			((AW_U32)0x00000020)	// Enabling send restart signal
#define I2C_RESTART_DIS			(~I2C_RESTART_EN)		// Disanbling I2C send restart signal
#define I2C_SPEED_FAST			((AW_U32)0x00000004)	// Fast mode (<=400Kb/S) or fast mode plus (<=1000Kb/S)
#define I2C_SPEED_LOW			((AW_U32)0x00000002)	// Standard mode (0 to 100Kb/S)
#define I2C_MASTER_EN			((AW_U32)0x00000001)	// Enabling I2C master mode
#define I2C_MASTER_DIS			((AW_U32)0xFFFFFFFE)	// Disanbling I2C master mode

/* I2C Interrupt Mask Macros */
#define I2CIM_GEN_CALL				((AW_U32)0x800)
#define I2CIM_START					((AW_U32)0x400)
#define I2CIM_STOP					((AW_U32)0x200)
#define I2CIM_ACTIVE				((AW_U32)0x100)
#define I2CIM_RX_DONE				((AW_U32)0x80)
#define I2CIM_TX_ABRT				((AW_U32)0x40)
#define I2CIM_RD_REQ				((AW_U32)0x20)
#define I2CIM_TX_EMPTY				((AW_U32)0x10)
#define I2CIM_TX_OVER				((AW_U32)0x08)
#define I2CIM_RX_FULL				((AW_U32)0x04)
#define I2CIM_RX_OVER				((AW_U32)0x02)
#define I2CIM_RX_UNDER				((AW_U32)0x01)
#define I2CIM_ALL					((AW_U32)0xFFF)		// All interrupt

/* I2C Interrupt State */
#define I2C_MAT_SAR				((AW_U32)0x00008000)	// Address matched (slave mode)
#define I2C_START_DET			((AW_U32)0x00000400)	// Start signal detected
#define I2C_CLR_MAT_SAR			((AW_U32)0x00000001)	// Clearing Mat_SAR interrupt flag
#define I2C_RX_OVER				((AW_U32)0x00000002)	// Receiving Overflow Interruption
#define I2C_RX_FULL				((AW_U32)0x00000004)	// Receiving full interruption
#define I2C_STOP_DE				((AW_U32)0x00000200)	// STOP Conditional Detection Bit
#define I2C_RD_REQ				((AW_U32)0x00000020)	// Other hosts request data from I2C
#define I2C_STATUS_ACTIVE		((AW_U32)0x00000001)
#define I2C_STATUS_TFNF			((AW_U32)0x00000002)	// Send FIFO full
#define I2C_STATUS_TFF			((AW_U32)0x00000004)
#define I2C_STATUS_RFNE			((AW_U32)0x00000008)	// Receive FIFO full
#define I2C_STATUS_RFF			((AW_U32)0x00000010)	// Receiving fifo full state bits

#define I2C_CMD_RX_MODE			((AW_U32)0x00000100)
#define I2C_CMD_TX_MODE			((AW_U32)0xFFFFFEFF)

#define I2C_PMUX_MODE			((AW_U32)0xF0FFFFFF)
#define UART_PMUX_FULL			((AW_U32)0x00F00000)
#define UART_PMUX_MODE			((AW_U32)0xFFAFFFFF)

#define I2C_TIMEOUT				(11500)		// Timeout judgment 10ms.

#ifdef I2C_TEST

#ifndef I2C_BUFF_LEN
#define I2C_BUFF_LEN (251U)
#endif
/**
 * @brief  I2C global variables
**/
	extern I2C_STATUS_TYPE_E g_i2c_status;
	extern AW_U8 g_i2c_rx_buff[I2C_BUFF_LEN];	// i2c receive buff
	extern AW_U8 g_i2c_tx_buff[I2C_BUFF_LEN];	// i2c send buff
#endif // I2C_TEST

/**
 * @brief  I2C macro definition function
**/

#define I2C_SET_MASK(int_flag)			(I2C0->INT_FLAG |= (int_flag))
#define I2C_CLEAN_MASK(int_flag)		(I2C0->INT_FLAG &= ~(int_flag))
#define I2C_SET_CMD_MODE(cmd_mode)		(I2C0->DA_BUF_CMD = (cmd_mode))

RET_STATUS_E i2c_init(I2C_HANDLE_TYPE_S *p_i2c_lib);
RET_STATUS_E i2c_read_bytes(AW_U16 read_len, AW_U8 *p_rx_buff);
RET_STATUS_E i2c_write_bytes(AW_U16 write_len, AW_U8 *p_tx_buff);
void i2c_irq(void);

#endif
#endif
